#include "complex.hpp"

#include <stdio.h> // 
#include <math.h>  // atan2, sqrt
#include <float.h> // DBL_EPSILON

// Тесты 
bool test_default_construct(){
	return (Complex().real() == 0.0) && (Complex().imag() == 0.0);
}
bool test_transform_construct(){
	return Complex(2.45).real() == 2.45;
}
bool test_construct(){
	return (Complex(2.56, 0.34).real() == 2.56) && (Complex(2.56, 0.34).imag() == 0.34);
}

bool test_modulo(){
	if(fabs(Complex(3.0,4.0).modulo() - 5.0) > DBL_EPSILON) return 0;
	return 1;
}

bool test_angle(){
	if(fabs(Complex(1.0,0.0).angle()) > DBL_EPSILON) 			return 0;
	if(fabs(Complex(0.0,1.0).angle() - M_PI/2) > DBL_EPSILON) 	return 0;
	if(fabs(Complex(1.0,1.0).angle() - M_PI/4) > DBL_EPSILON) 	return 0;

	return 1;
}

bool test_assign(){
	Complex Z;
	Z = Complex(0.4,-0.2);
	if(Z.real() != 0.4 || Z.imag() != -0.2) return 0;
	return 1;
}

bool test_sum(){
	Complex Z = Complex(2.4,4.7) + Complex(-1.4,3.5);
	if( fabs(Z.real() - 1.0) > DBL_EPSILON || 
		fabs(Z.imag() - 8.2) > DBL_EPSILON) return 0;
	return 1;
}
bool test_sub(){
	Complex Z = Complex(2.4,4.7) - Complex(-1.4,3.5);
	if( fabs(Z.real() - 3.8) > DBL_EPSILON || 
		fabs(Z.imag() - 1.2) > DBL_EPSILON) return 0;
	return 1;
}
bool test_mul(){
	Complex Z = Complex(2.5,-0.3)*Complex(0.2,0.4);
	if(fabs(Z.real() - 0.62) > DBL_EPSILON ||
	   fabs(Z.imag() - 0.94) > DBL_EPSILON) return 0;	   		
	return 1;
}
bool test_div(){
	Complex Z = Complex(2.5,-0.3)/Complex(0.2,0.4);
	if(fabs(Z.real() - 1.9) > 10*DBL_EPSILON||   // bad accuracy
	   fabs(Z.imag() + 5.3) > 10*DBL_EPSILON) return 0;	   		
	return 1;
}
bool test_eq(){
	return Complex(2.5,-0.45) == Complex(2.5,-0.45);
}

void do_all_test(){
	printf("Running tests.\n");
	printf("\t%s : Default constructor\n", (test_default_construct())? "PASS" : "FAIL");
	printf("\t%s : Transform constructor\n", (test_transform_construct())? "PASS": "FAIL");
	printf("\t%s : Constructor\n", (test_construct())? "PASS" : "FAIL");
	printf("\t%s : modulo\n", (test_modulo())? "PASS" : "FAIL");
	printf("\t%s : angle\n", (test_angle())? "PASS" : "FAIL");
	printf("\t%s : assign\n", (test_assign())? "PASS" : "FAIL");
	printf("\t%s : sum\n", (test_sum())? "PASS" : "FAIL");
	printf("\t%s : sub\n", (test_sub())? "PASS" : "FAIL");
	printf("\t%s : mul\n", (test_mul())? "PASS" : "FAIL");
	printf("\t%s : div\n", (test_div())? "PASS" : "FAIL");
	printf("\t%s : eq\n", (test_eq())? "PASS" : "FAIL");
}

int main(){
	do_all_test();

	return 0;
}
